package io.gitee.zhucan123.core.config;

import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author: zhuCan
 * @date: 2019/12/6 18:25
 * @description: This encoder adds support for pageable, which will be applied to the query parameters.
 *    * https://github.com/spring-cloud/spring-cloud-netflix/issues/556#issuecomment-254144593
 */
public class PageableEncoder implements Encoder {

  private final Encoder delegate;

  public PageableEncoder(Encoder delegate) {
    this.delegate = delegate;
  }

  @Override
  public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {

    if (object instanceof Pageable) {
      Pageable pageable = (Pageable) object;
      template.query("page", pageable.getPageNumber() + "");
      template.query("size", pageable.getPageSize() + "");

      if (pageable.getSort() != null) {
        Collection<String> existingSorts = template.queries().get("sort");
        List<String> sortQueries = existingSorts != null ? new ArrayList<>(existingSorts) : new ArrayList<>();
        for (Sort.Order order : pageable.getSort()) {
          sortQueries.add(order.getProperty() + "%2C" + order.getDirection());
        }
        template.query("sort", sortQueries);
      }

    } else {
      delegate.encode(object, bodyType, template);
    }
  }
}
